﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Threading;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
using System.Reflection;
using System.IO;
using System.ServiceProcess;

using PersistenceObject.Framework;
using PersistenceObject.Framework.Expressions;

using FundSms.Server.Model;
using FundSms.SmsLib;

namespace FundSms.Server.Platform
{
    public class Program : ServiceBase
    {
        private static readonly string DataKey = "Sms";

        //用于锁定
        private static object LockObject = new Object();
        //企业列表
        private static IList<Enterprise> Enterprises;
        //企业列表字典
        private static Dictionary<string,Enterprise> DicEnterprises;

        //通道列表
        private static IList<Channel> Channels;
        //通道列表
        private static Dictionary<string,Channel> DicChannels;
        //一般发送规则列表
        private static Dictionary<string, IList<EnterpriseChannelRule>> ChannelRules;
        //高级发送规则列表
        private static EnterpriseChannelRuleAdvanceCodeList ChannelAdvanceRules;
        //自定义发送规则列表
        private static EnterpriseChannelRuleCustomCodeList ChannelCustomRules;

        //高级规则通道扩展号数据缓存
        private static Dictionary<string, RuleSignExtValue> ChannelAdvanceSignExt;
        //普通规则通道扩展号数据缓存
        private static Dictionary<string, RuleSignExtValue> ChannelNormalSignExt;
        
        //通道类型
        private static IList<ChannelType> ChannelTypes;
        //黑名单
        //private static Dictionary<string, Dictionary<string, BlackList>> BlackLists;

        //定时清理控制台
        private static System.Timers.Timer timerConsole = new System.Timers.Timer();
        //定时更新企业数据
        private static System.Timers.Timer timerEnterprise = new System.Timers.Timer();
        //定时更新通道数据
        private static System.Timers.Timer timerChannel = new System.Timers.Timer();
        //定时更新普通规则数据
        private static System.Timers.Timer timerRule = new System.Timers.Timer();
        //定时更新高级规则数据
        private static System.Timers.Timer timerAdvanceRule = new System.Timers.Timer();
        //定时更新自定义规则数据
        private static System.Timers.Timer timerCustomRule = new System.Timers.Timer();
        //定时更新黑名单
        //private static System.Timers.Timer timerBlackList = new System.Timers.Timer();

        private static int RefreshConsoleTime = Convert.ToInt32(ConfigurationManager.AppSettings["RefreshConsoleTime"]) * 1000;
        private static int RefreshEnterpriseTime = Convert.ToInt32(ConfigurationManager.AppSettings["RefreshEnterpriseTime"]) * 1000;
        private static int RefreshChannelTime = Convert.ToInt32(ConfigurationManager.AppSettings["RefreshChannelTime"]) * 1000;
        private static int RefreshRuleTime = Convert.ToInt32(ConfigurationManager.AppSettings["RefreshRuleTime"]) * 1000;
        private static int RefreshAdvanceRuleTime = Convert.ToInt32(ConfigurationManager.AppSettings["RefreshAdvanceRuleTime"]) * 1000;
        private static int RefreshCustomRuleTime = Convert.ToInt32(ConfigurationManager.AppSettings["RefreshCustomRuleTime"]) * 1000;
        //private static int RefreshBlackListTime = Convert.ToInt32(ConfigurationManager.AppSettings["RefreshBlackListTime"]) * 1000;

        private static int SleepTime = Convert.ToInt32(ConfigurationManager.AppSettings["SleepTime"]);
        private static int SupportEnterpriseCount = Convert.ToInt32(ConfigurationManager.AppSettings["SupportEnterpriseCount"]);
        private static int SupportChannelCount = Convert.ToInt32(ConfigurationManager.AppSettings["SupportChannelCount"]);
        private static int TransferSmsCount = Convert.ToInt32(ConfigurationManager.AppSettings["TransferSmsCount"]);
        private static int Debug = 0;

        private static string ServiceRealName = ConfigurationManager.AppSettings["ServiceName"];
        private static string ServiceDisPlayName = ConfigurationManager.AppSettings["ServiceDisPlayName"];
        private static string ServiceDescription = ConfigurationManager.AppSettings["ServiceDescription"];

        private static bool LogToFile = ConfigurationManager.AppSettings["LogToFile"] == "1" ? true : false;

        private static object obj = new object();

        //定义发送线程
        private static Thread[] SendThreads;
        //定义接收返回线程
        private static Thread[] ReceiveThreads;
        //当前的企业数
        private static int CurrentEnterpriseCount;
        //当前的通道数
        private static int CurrentChannelCount;
        //是否处于停止服务状态下
        private static bool Stopped = false;
        //判断每个线程是否已经跳出循环
        private static Dictionary<string,bool> ThreadStatus = new Dictionary<string,bool>();

        //服务所在路径
        private static string ServicePath =  Application.ExecutablePath;
        private static string ServiceDirectory = Path.GetDirectoryName(ServicePath);

        //private static Portal portal;

        #region 应用程序入口
        static void Main(string[] args)
        {
            Thread.GetDomain().UnhandledException += new UnhandledExceptionEventHandler(Program_UnhandledException);
            Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);

            bool exists = ServiceControl.CheckService(ServiceRealName);

            if (args.Length == 0)
            {
                ServiceBase.Run(new ServiceBase[] { new Program() });
            }
            else
            {
                string parm = args[0].ToLower();

                switch (parm)
                {
                    case "-debug":
                    case "/debug":

                        Debug = 1;

                        if (exists)
                        {
                            ServiceControllerStatus status = ServiceControl.GetServiceStatus(ServiceRealName);

                            if (status != ServiceControllerStatus.Stopped)
                            {
                                Console.WriteLine(GetDateTime() + ServiceRealName + " 服务正在运行，无法进入调试状态。请先停止该服务");
                                Console.ReadLine();
                            }
                            else
                            {
                                InitilizeCompoment();
                            }
                        }
                        else
                        {
                            InitilizeCompoment();
                        }


                        break;

                    case "-install":
                    case "-setup":
                    case "/install":
                    case "/setup":

                        if (exists)
                        {
                            Console.WriteLine(GetDateTime() + ServiceRealName + " 服务已经存在，如果您想升级服务，请先卸载该服务");
                            Console.ReadLine();
                        }
                        else
                        {
                            Console.WriteLine(GetDateTime() + ServicePath);

                            bool result = ServiceControl.InstallService(ServicePath, ServiceRealName, ServiceDisPlayName, ServiceDescription);

                            if (result)
                            {
                                Console.WriteLine(GetDateTime() + "服务安装成功");
                                Console.WriteLine(GetDateTime() + "正在启动服务...");

                                ServiceControl.StartService(ServiceRealName);

                                while (!(ServiceControl.GetServiceStatus(ServiceRealName) == ServiceControllerStatus.Running))
                                {
                                    Thread.Sleep(SleepTime);
                                }

                                Console.WriteLine(GetDateTime() + "服务已经启动");
                            }
                            else
                            {
                                Console.WriteLine(GetDateTime() + "服务安装失败");
                            }

                            Console.ReadLine();
                        }
                        break;

                    case "-uninstall":
                    case "-remove":
                    case "/uninstall":
                    case "/remove":

                        if (!exists)
                        {
                            Console.WriteLine(GetDateTime() + ServiceRealName + " 服务尚未安装");
                        }
                        else
                        {
                            bool result = ServiceControl.UnInstallService(ServiceRealName);

                            if (!result)
                            {
                                Console.WriteLine(GetDateTime() + "服务卸载失败");
                            }
                            else
                            {
                                Console.WriteLine(GetDateTime() + "服务卸载成功");
                            }
                        }

                        Console.ReadLine();

                        break;

                }

            }
        }

        static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
        {
            Output("未处理A：" + e.Exception.Message, ConsoleColor.Red, true);
        }

        static void Program_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            if (e.ExceptionObject is System.Exception)
            {
                Output("未处理P：" + ((System.Exception)e.ExceptionObject).Message, ConsoleColor.Red, true);
            }

        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {

            }

            base.Dispose(disposing);
        }

        public Program()
        {
            base.ServiceName = ServiceRealName;
            base.AutoLog = true;
        }

        #endregion

        #region 初始化服务设置
        protected override void OnStart(string[] args)
        {
            InitilizeCompoment();
        }

        protected override void OnStop()
        {
            //停止定时器
            timerAdvanceRule.Enabled = false;
            //timerBlackList.Enabled = false;
            timerChannel.Enabled = false;
            timerConsole.Enabled = false;
            timerEnterprise.Enabled = false;
            timerRule.Enabled = false;

            //通知线程结束循环
            Stopped = true;

            while (!AllStop())
            {
                Thread.Sleep(SleepTime);
            }
        }

        /// <summary>
        /// 判断工作线程是否已经都停止了
        /// </summary>
        /// <returns></returns>
        private static bool AllStop()
        {
            try
            {
                lock (obj)
                {
                    foreach (bool value in ThreadStatus.Values)
                    {
                        if (!value)
                        {
                            return false;
                        }
                    }
                }

                return true;
            }
            catch (Exception e)
            {
                Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red, true);

                return false;
            }
        }

        #endregion

        #region 初始化应用程序
        /// <summary>
        /// 初始化应用程序
        /// </summary>
        private static void InitilizeCompoment()
        {
            if (Debug == 1)
            {
                Console.Title = ServiceDisPlayName;
            }

            //设定用户信息
            Enterprises = GetEnterprise();
            DicEnterprises = GetEnterpriseDic();
            Channels = GetChannel();
            DicChannels = GetDicChannel();
            ChannelTypes = GetChannelType();
            //BlackLists = GetBlackList();
            ChannelRules = GetChannelRule(Enterprises);
            ChannelNormalSignExt = GetSignExtNormal();
            ChannelAdvanceRules = GetAdvanceChannelRule(Enterprises);
            ChannelAdvanceSignExt = GetSignExtAdvance();
            ChannelCustomRules = GetCustomChannelRule(Enterprises);

            Output("载入初始数据",true);

            //设置初始企业数
            CurrentEnterpriseCount = Enterprises.Count;
            //设置初始通道数
            CurrentChannelCount = Channels.Count;

            Output("当前企业数：" + CurrentEnterpriseCount);

            //初始化定时器
            InitilizeTimer();

            Output("初始化定时器",true);

            if (CurrentEnterpriseCount > SupportEnterpriseCount)
            {
                Output("企业超过最大支持数" + SupportEnterpriseCount, true);
                return;
            }

            if (CurrentChannelCount > SupportChannelCount)
            {
                Output("通道超过最大支持数" + SupportChannelCount, true);
                return;
            }

            //初始化线程
            SendThreads = new Thread[SupportEnterpriseCount];
            ReceiveThreads = new Thread[SupportChannelCount];

            ThreadStatus.Clear();

            //初始化线程状态，用于等待线程结束
            foreach (Enterprise enterprise in Enterprises)
            {
                ThreadStatus.Add(enterprise.EnterpriseCode, false);
            }

            int i = 0;

            foreach (Enterprise enterprise in Enterprises)
            {
                SendThreads[i] = new Thread(new ParameterizedThreadStart(SendToChannel));
                SendThreads[i].Name = enterprise.EnterpriseCode;
                SendThreads[i].IsBackground = false;
                SendThreads[i].Priority = GetThreadPriority(enterprise.Priority);
                SendThreads[i].Start(enterprise.EnterpriseCode);

                i++;
            }

            int j = 0;

            foreach (Channel channel in Channels)
            {
                ReceiveThreads[j] = new Thread(new ParameterizedThreadStart(ReceiveFromChannel));
                ReceiveThreads[j].Name = channel.ChannelCode;
                ReceiveThreads[j].IsBackground = true;
                ReceiveThreads[j].Start(channel);

                j++;
            }

            Output("工作线程初始化",true);

            if (Debug == 1)
            {
                Console.ReadLine();
            }
        }
        #endregion

        #region 业务逻辑

        /// <summary>
        /// 将数据送到对应通道表
        /// </summary>
        /// <param name="o">企业号</param>
        private static void SendToChannel(object o)
        {
            string enterprisecode = o.ToString();

            string account = string.Empty;
            string sendmethod = string.Empty;
            string channelcode = string.Empty;
            string costmethod = string.Empty;
            IList<MT_TEST> sendlist = null;

            RuleSignExtKey keynormal = null;
            RuleSignExtKeyAdvance keyadvance = null;

            string sign = string.Empty;
            string extcoe = string.Empty;
            string key = string.Empty;

            Enterprise enterprise = null;

            while (true)
            {
                //如果处于停止服务请求下
                if (Stopped)
                {
                    lock (obj)
                    {
                        ThreadStatus[enterprisecode] = true;
                    }
                    //跳出循环
                    break;
                }

                if (DicEnterprises.ContainsKey(enterprisecode))
                {
                    enterprise = DicEnterprises[enterprisecode];

                    account = enterprise.Account.ToUpper();
                    sendmethod = enterprise.SendMethod;
                    costmethod = enterprise.CostMethod;
                }
                else
                {
                    Thread.Sleep(RefreshEnterpriseTime);

                    continue;
                }

                if (enterprise.EnterpriseStatus.ToLower() != "normal")
                {
                    Output("["+account+"]" + "休眠");

                    Thread.Sleep(RefreshEnterpriseTime);

                    continue;
                }
                else
                {

                    Thread.Sleep(SleepTime);
                }

                if (sendmethod == "normal")
                {
                    if (ChannelRules.ContainsKey(enterprisecode))
                    {
                        try
                        {
                            sendlist = QueryOperate<MT_TEST>.Create(DataKey).Where(MT_TEST._EnterpriseCode == enterprisecode & MT_TEST._SmsStatus == 0).OrderBy(MT_TEST._Priority, MT_TEST._LogID).From(new Table("SMS_MT_" + account)).Top(TransferSmsCount).List();
                        }
                        catch (Exception e)
                        {
                            Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red, true);

                            Thread.Sleep(SleepTime);

                            continue;
                        }

                        if (sendlist.Count > 0)
                        {
                            //获得该企业的通道规则
                            IList<EnterpriseChannelRule> rules = ChannelRules[enterprisecode];
                            //获得通道规则下本次发送的通道号
                            channelcode = GetChannelCode(rules);

                            if (channelcode != string.Empty)
                            {
                                if (!DicChannels.ContainsKey(channelcode))
                                {
                                    Thread.Sleep(SleepTime);

                                    continue;
                                }
                                else
                                {
                                    if (DicChannels[channelcode].ChannelStatus.ToLower() != "normal")
                                    {
                                        Thread.Sleep(SleepTime);

                                        continue;
                                    }
                                }

                                keynormal = new RuleSignExtKey();
                                keynormal.ChannelCode = channelcode;
                                keynormal.EnterpriseCode = enterprisecode;

                                key = keynormal.ToString();

                                if (ChannelNormalSignExt.ContainsKey(key))
                                {
                                    sign = ChannelNormalSignExt[key].Sign;
                                    extcoe = ChannelNormalSignExt[key].ExtCode;
                                }

                                foreach (MT_TEST mt in sendlist)
                                {

                                    //if (BlackLists.ContainsKey(enterprisecode))
                                    //{

                                    //    if (BlackLists[enterprisecode].ContainsKey(mt.Mobile))
                                    //    {
                                    //        //如果在黑名单里
                                    //        UpdateOperate<MT_TEST>.Create(DataKey).From(new Table("SMS_MT_" + account)).Fields(
                                    //        FieldValue.Create(MT_TEST._SmsStatus, -1), FieldValue.Create(MT_TEST._SmsStatusRemark, "b"), FieldValue.Create(MT_TEST._LastUpdate, DateTime.Now)
                                    //        ).Where(MT_TEST._LogID == mt.LogID).Execute();

                                    //        Output("[" + account + "]" + "黑名单：" + mt.Mobile);

                                    //        continue;
                                    //    }
                                    //}

                                    //将数据插到对应的通道表
                                    Channel_HZUNICOM channel = new Channel_HZUNICOM();
                                    channel.ChannelCode = channelcode;
                                    channel.CreateDate = mt.CreateDate;
                                    channel.EnterpriseCode = mt.EnterpriseCode;
                                    channel.LastUpdate = DateTime.Now;
                                    channel.LogCode = mt.LogCode;
                                    channel.Mobile = mt.Mobile;
                                    channel.MobileType = mt.MobileType;
                                    channel.CostMethod = costmethod;
                                    channel.Priority = mt.Priority;
                                    channel.Ready1 = mt.Ready1;
                                    channel.Ready2 = mt.Ready2;
                                    channel.Ready3 = mt.Ready3;
                                    channel.Ready4 = mt.Ready4;
                                    channel.Ready5 = mt.Ready5;
                                    channel.Seed = mt.Seed;
                                    channel.SmsID = mt.SmsID;
                                    channel.GateWayID = 0;
                                    channel.GateWayCode = string.Empty;
                                    channel.SmsStatus = 0;
                                    channel.SmsStatusRemark = string.Empty;
                                    channel.ErrorNumber = 0;

                                    channel.SubID = extcoe;
                                    channel.Content = mt.Content + sign;

                                    try
                                    {
                                        InsertOperate<Channel_HZUNICOM>.Create(DataKey).From(new Table("SMS_CHANNEL_" + channelcode)).Execute(channel);

                                        UpdateOperate<MT_TEST>.Create(DataKey).From(new Table("SMS_MT_" + account)).Fields(
                                        FieldValue.Create(MT_TEST._SmsStatus, 1), FieldValue.Create(MT_TEST._ChannelCode, channelcode), FieldValue.Create(MT_TEST._LastUpdate, DateTime.Now))
                                        .Where(MT_TEST._LogID == mt.LogID).Execute();

                                    }
                                    catch (Exception e)
                                    {
                                        Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red, true);
                                    }

                                    Output("[" + account + "][" + channelcode + "][normal] 分配" + sendlist.Count + " 条数据");
                                }
                            }
                        }
                    }

                }
                else if (sendmethod == "advance")
                {
                    //查找每个类型的短信
                    foreach (ChannelType type in ChannelTypes)
                    {
                        try
                        {
                            sendlist = QueryOperate<MT_TEST>.Create(DataKey).Where(MT_TEST._EnterpriseCode == enterprisecode & MT_TEST._SmsStatus == 0 & MT_TEST._MobileType == type.ChannelTypeCode).OrderBy(MT_TEST._Priority, MT_TEST._LogID).From(new Table("SMS_MT_" + account)).Top(TransferSmsCount).List();
                        }
                        catch (Exception e)
                        {
                            Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red, true);

                            Thread.Sleep(SleepTime);

                            continue;
                        }

                        if (sendlist.Count > 0)
                        {
                            //获得本类型本次的通道号

                            if (ChannelAdvanceRules.ContainsKey(enterprisecode))
                            {
                                if (ChannelAdvanceRules[enterprisecode].ContainsKey(type.ChannelTypeCode))
                                {

                                    EnterpriseChannelRuleAdvanceItemList advancerules = ChannelAdvanceRules[enterprisecode][type.ChannelTypeCode];
                                    //应用规则
                                    channelcode = GetAdvanceChannelCode(advancerules);

                                    if (channelcode != string.Empty)
                                    {
                                        if (!DicChannels.ContainsKey(channelcode))
                                        {
                                            Thread.Sleep(SleepTime);

                                            continue;
                                        }
                                        else
                                        {
                                            if (DicChannels[channelcode].ChannelStatus.ToLower() != "normal")
                                            {
                                                Thread.Sleep(SleepTime);

                                                continue;
                                            }
                                        }

                                        //获得签名和扩展号
                                        keyadvance = new RuleSignExtKeyAdvance();
                                        keyadvance.ChannelCode = channelcode;
                                        keyadvance.EnterpriseCode = enterprisecode;
                                        keyadvance.RuleType = type.ChannelTypeCode;

                                        key = keyadvance.ToString();

                                        if (ChannelAdvanceSignExt.ContainsKey(key))
                                        {
                                            sign = ChannelAdvanceSignExt[key].Sign;
                                            extcoe = ChannelAdvanceSignExt[key].ExtCode;
                                        }

                                        foreach (MT_TEST mt in sendlist)
                                        {
                                            //if (BlackLists.ContainsKey(enterprisecode))
                                            //{
                                            //    if (BlackLists[enterprisecode].ContainsKey(mt.Mobile))
                                            //    {
                                            //        //如果在黑名单里
                                            //        UpdateOperate<MT_TEST>.Create(DataKey).From(new Table("SMS_MT_" + account)).Fields(
                                            //        FieldValue.Create(MT_TEST._SmsStatus, -1), FieldValue.Create(MT_TEST._SmsStatusRemark, "b"), FieldValue.Create(MT_TEST._LastUpdate, DateTime.Now)
                                            //        ).Where(MT_TEST._LogID == mt.LogID).Execute();

                                            //        continue;
                                            //    }
                                            //}

                                            //将数据插到对应的通道表
                                            Channel_HZUNICOM channel = new Channel_HZUNICOM();
                                            channel.ChannelCode = channelcode;
                                            channel.CreateDate = mt.CreateDate;
                                            channel.EnterpriseCode = mt.EnterpriseCode;
                                            channel.LastUpdate = DateTime.Now;
                                            channel.LogCode = mt.LogCode;
                                            channel.Mobile = mt.Mobile;
                                            channel.MobileType = mt.MobileType;
                                            channel.Priority = mt.Priority;
                                            channel.CostMethod = costmethod;
                                            channel.Ready1 = mt.Ready1;
                                            channel.Ready2 = mt.Ready2;
                                            channel.Ready3 = mt.Ready3;
                                            channel.Ready4 = mt.Ready4;
                                            channel.Ready5 = mt.Ready5;
                                            channel.Seed = mt.Seed;
                                            channel.SmsID = mt.SmsID;
                                            channel.GateWayID = 0;
                                            channel.GateWayCode = string.Empty;
                                            channel.SmsStatus = 0;
                                            channel.SmsStatusRemark = string.Empty;
                                            channel.ErrorNumber = 0;

                                            channel.SubID = extcoe;
                                            channel.Content = mt.Content + sign;

                                            try
                                            {
                                                InsertOperate<Channel_HZUNICOM>.Create(DataKey).From(new Table("SMS_CHANNEL_" + channelcode)).Execute(channel);

                                                UpdateOperate<MT_TEST>.Create(DataKey).From(new Table("SMS_MT_" + account)).Fields(
                                                FieldValue.Create(MT_TEST._SmsStatus, 1), FieldValue.Create(MT_TEST._ChannelCode, channelcode), FieldValue.Create(MT_TEST._LastUpdate, DateTime.Now))
                                                .Where(MT_TEST._LogID == mt.LogID).Execute();
                                            }
                                            catch (Exception e)
                                            {
                                                Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red, true);
                                            }
                                        }

                                    }
                                }
                            }

                            Output("[" + account + "][" + channelcode + "][advance] 分配" + sendlist.Count + " 条数据");
                        }
                    }
                }
                else if (sendmethod == "custom")
                {
                    if (ChannelCustomRules.ContainsKey(enterprisecode))
                    {
                        //查找每个类型的短信
                        foreach (ChannelType type in ChannelTypes)
                        {
                            try
                            {
                                sendlist = QueryOperate<MT_TEST>.Create(DataKey).Where(MT_TEST._EnterpriseCode == enterprisecode & MT_TEST._SmsStatus == 0 & MT_TEST._MobileType == type.ChannelTypeCode).OrderBy(MT_TEST._Priority, MT_TEST._LogID).From(new Table("SMS_MT_" + account)).Top(TransferSmsCount).List();
                            }
                            catch (Exception e)
                            {
                                Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red, true);

                                Thread.Sleep(SleepTime);

                                continue;
                            }

                            if (sendlist.Count > 0)
                            {
                                if (ChannelCustomRules[enterprisecode].ContainsKey(type.ChannelTypeCode))
                                {
                                    channelcode = ChannelCustomRules[enterprisecode][type.ChannelTypeCode].ChannelCode;

                                    if (!DicChannels.ContainsKey(channelcode))
                                    {
                                        Thread.Sleep(SleepTime);

                                        continue;
                                    }
                                    else
                                    {
                                        if (DicChannels[channelcode].ChannelStatus.ToLower() != "normal")
                                        {
                                            Thread.Sleep(SleepTime);

                                            continue;
                                        }
                                    }

                                    sign = ChannelCustomRules[enterprisecode][type.ChannelTypeCode].Sign;
                                    extcoe = ChannelCustomRules[enterprisecode][type.ChannelTypeCode].ExtCode;

                                    foreach (MT_TEST mt in sendlist)
                                    {
                                        //if (BlackLists.ContainsKey(enterprisecode))
                                        //{
                                        //    if (BlackLists[enterprisecode].ContainsKey(mt.Mobile))
                                        //    {
                                        //        //如果在黑名单里
                                        //        UpdateOperate<MT_TEST>.Create(DataKey).From(new Table("SMS_MT_" + account)).Fields(
                                        //        FieldValue.Create(MT_TEST._SmsStatus, -1), FieldValue.Create(MT_TEST._SmsStatusRemark, "b"), FieldValue.Create(MT_TEST._LastUpdate, DateTime.Now)
                                        //        ).Where(MT_TEST._LogID == mt.LogID).Execute();

                                        //        continue;
                                        //    }
                                        //}

                                        //将数据插到对应的通道表
                                        Channel_HZUNICOM channel = new Channel_HZUNICOM();
                                        channel.ChannelCode = channelcode;
                                        channel.CreateDate = mt.CreateDate;
                                        channel.EnterpriseCode = mt.EnterpriseCode;
                                        channel.LastUpdate = DateTime.Now;
                                        channel.LogCode = mt.LogCode;
                                        channel.Mobile = mt.Mobile;
                                        channel.MobileType = mt.MobileType;
                                        channel.Priority = mt.Priority;
                                        channel.CostMethod = costmethod;
                                        channel.Ready1 = mt.Ready1;
                                        channel.Ready2 = mt.Ready2;
                                        channel.Ready3 = mt.Ready3;
                                        channel.Ready4 = mt.Ready4;
                                        channel.Ready5 = mt.Ready5;
                                        channel.Seed = mt.Seed;
                                        channel.SmsID = mt.SmsID;
                                        channel.GateWayID = 0;
                                        channel.GateWayCode = string.Empty;
                                        channel.SmsStatus = 0;
                                        channel.SmsStatusRemark = string.Empty;
                                        channel.ErrorNumber = 0;

                                        channel.SubID = extcoe;
                                        channel.Content = mt.Content + sign;

                                        try
                                        {
                                            InsertOperate<Channel_HZUNICOM>.Create(DataKey).From(new Table("SMS_CHANNEL_" + channelcode)).Execute(channel);

                                            UpdateOperate<MT_TEST>.Create(DataKey).From(new Table("SMS_MT_" + account)).Fields(
                                            FieldValue.Create(MT_TEST._SmsStatus, 1), FieldValue.Create(MT_TEST._ChannelCode, channelcode), FieldValue.Create(MT_TEST._LastUpdate, DateTime.Now))
                                            .Where(MT_TEST._LogID == mt.LogID).Execute();
                                        }
                                        catch (Exception e)
                                        {
                                            Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red, true);
                                        }
                                    }

                                    Output("[" + account + "][" + channelcode + "][custom] 分配" + sendlist.Count + " 条数据");
                                }
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 从通道表里接收状态数据
        /// </summary>
        /// <param name="o">企业实体</param>
        private static void ReceiveFromChannel(object o)
        {
            Channel channel = (Channel)o;
            string channelcode = channel.ChannelCode;
            IList<Channel_HZUNICOM> listchannel;
            string account = string.Empty;
            string enterprisecode = string.Empty;
            
            while (true)
            {
                //如果处于停止服务请求下
                if (Stopped)
                {
                    //跳出循环
                    break;
                }

                try
                {
                    listchannel = QueryOperate<Channel_HZUNICOM>.Create(DataKey).From(new Table("SMS_CHANNEL_" + channelcode)).Top(TransferSmsCount).OrderBy(Channel_HZUNICOM._LogID).Where(Channel_HZUNICOM._SmsStatus == 2 | Channel_HZUNICOM._SmsStatus == -1).List();
                }
                catch (Exception e)
                {
                    Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red,true);

                    Thread.Sleep(SleepTime);

                    continue;
                }

                if (listchannel.Count > 0)
                {
                    //更新下行表并删除数据
                    foreach (Channel_HZUNICOM sms in listchannel)
                    {
                        enterprisecode = sms.EnterpriseCode;
                        account = DicEnterprises[enterprisecode].Account;

                        using (IDataSession ds = new DataSession(DataKey))
                        {
                            ds.Open();
                            try
                            {
                                ds.BeginTran();
                                UpdateOperate<MT_TEST>.Create(ds).From(new Table("SMS_MT_" + account)).Fields(FieldValue.Create(MT_TEST._SmsStatus, sms.SmsStatus), FieldValue.Create(MT_TEST._LastUpdate, DateTime.Now), FieldValue.Create(MT_TEST._SmsStatusRemark, ConvertSmsStatus(sms.SmsStatusRemark))).Where(MT_TEST._LogCode == sms.LogCode).Execute();
                                DeleteOperate<Channel_HZUNICOM>.Create(ds).From(new Table("SMS_CHANNEL_" + channelcode)).Where(Channel_HZUNICOM._LogID == sms.LogID).Execute();
                                ds.Commit();
                            }
                            catch (Exception e)
                            {
                                try { ds.RollBack(); }
                                catch { }
                                Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red, true);
                            }
                        }
                    }

                    Output("[" + channelcode + "][" + account + "][" + enterprisecode +"]接收状态数据" + listchannel.Count + "条");
                }

                Thread.Sleep(SleepTime);
            }
        }

        /// <summary>
        /// 转化通道状态
        /// </summary>
        /// <param name="remark"></param>
        /// <returns></returns>
        private static string ConvertSmsStatus(string remark)
        {
            if (remark.IndexOf("xw") >= 0)
            {
                return "a";
            }

            if (remark.Length > 1)
            {
                return remark.Substring(0, 1);
            }
            else
            {
                return remark;
            }
        }

        /// <summary>
        /// 定时管理线程
        /// </summary>
        private static void ManageThreads()
        {
            //判断是否有新企业
            if (CurrentEnterpriseCount < Enterprises.Count)
            {
                if (Enterprises.Count <= SupportEnterpriseCount)
                {
                    int dif = Enterprises.Count - CurrentEnterpriseCount;

                    for (int i = 0; i < dif; i++)
                    {
                        SendThreads[CurrentEnterpriseCount + i] = new Thread(new ParameterizedThreadStart(SendToChannel));
                        SendThreads[CurrentEnterpriseCount + i].Name = Enterprises[CurrentEnterpriseCount + i].EnterpriseCode;
                        SendThreads[CurrentEnterpriseCount + i].IsBackground = false;
                        SendThreads[CurrentEnterpriseCount + i].Priority = GetThreadPriority(Enterprises[CurrentEnterpriseCount + i].Priority);
                        SendThreads[CurrentEnterpriseCount + i].Start(Enterprises[CurrentEnterpriseCount + i].EnterpriseCode);

                        ThreadStatus.Add(Enterprises[CurrentEnterpriseCount + i].EnterpriseCode, false);

                        Output("新增企业：" + Enterprises[CurrentEnterpriseCount + i].EnterpriseCode, true);
                    }

                    Output("新增企业数：" + dif,true);

                    CurrentEnterpriseCount = Enterprises.Count;

                    Output("当前企业数：" + CurrentEnterpriseCount,true);
                }
                else
                {
                    Output("当前企业数：" + Enterprises.Count + "，超过上限", true);
                }
            }

            //更新优先级
            foreach (Enterprise enterprise in Enterprises)
            {
                ThreadPriority priority = GetThreadPriority(enterprise.Priority);

                for (int i = 0; i < CurrentEnterpriseCount; i++)
                {
                    if (SendThreads[i].Priority != priority)
                    {
                        SendThreads[i].Priority = priority;
                    }
                }
            }

            Output("更新优先级",true);

        }

        /// <summary>
        /// 定时管理通道
        /// </summary>
        private static void ManageChannels()
        {
            //判断是否有新通道
            if (CurrentChannelCount < Channels.Count)
            {
                if (Channels.Count <= SupportChannelCount)
                {
                    int dif = Channels.Count - CurrentChannelCount;

                    for (int i = 0; i < dif; i++)
                    {
                        ReceiveThreads[CurrentChannelCount + i] = new Thread(new ParameterizedThreadStart(ReceiveFromChannel));
                        ReceiveThreads[CurrentChannelCount + i].Name = Channels[CurrentChannelCount + i].ChannelCode;
                        ReceiveThreads[CurrentChannelCount + i].IsBackground = true;
                        ReceiveThreads[CurrentChannelCount + i].Start(Channels[CurrentChannelCount + i]);

                        Output("新增通道：" + Channels[CurrentChannelCount + i].ChannelCode, true);

                    }

                    Output("新增通道数：" + dif,true);

                    CurrentChannelCount = Channels.Count;

                    Output("当前通道数：" + CurrentChannelCount);
                }

            }
        }

        /// <summary>
        /// 获得指定的线程优先级
        /// </summary>
        /// <param name="priority">指定优先等级</param>
        /// <returns>线程优先级</returns>
        private static ThreadPriority GetThreadPriority(int priority)
        {
            ThreadPriority threadpriority = ThreadPriority.Normal;

            if (priority == 1)
            {
                threadpriority = ThreadPriority.Lowest;
            }
            else if (priority == 2)
            {
                threadpriority = ThreadPriority.BelowNormal;
            }
            else if (priority == 3)
            {
                threadpriority = ThreadPriority.Normal;
            }
            else if (priority == 4)
            {
                threadpriority = ThreadPriority.AboveNormal;
            }
            else if (priority == 5)
            {
                threadpriority = ThreadPriority.Highest;
            }

            return threadpriority;
        }

        #endregion

        #region 粒度控制
        /// <summary>
        /// 根据种子返回该企业的通道号，粗粒度控制，速度慢，精确，高级模式
        /// </summary>
        /// <param name="rules"></param>
        /// <param name="seed"></param>
        /// <returns></returns>
        /*
        private static string GetAdvanceChannelCode(Dictionary<string, EnterpriseChannelRuleAdvance> rules, int seed)
        {
            if (rules.Count == 1)
            {
                return rules[0].ChannelCode;
            }
            else
            {
                for (int i = 0; i < rules.Count; i++)
                {
                    if (seed >= rules[i].BeginSendPercent && seed <= rules[i].EndSendPercent)
                    {
                        return rules[i].ChannelCode;
                    }
                }
            }

            return string.Empty;
        }
        */
        /// <summary>
        /// 粗粒度控制，高级模式
        /// </summary>
        /// <param name="rules"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private static string GetAdvanceChannelCode(EnterpriseChannelRuleAdvanceItemList rules)
        {
            int seed = new Random(Guid.NewGuid().GetHashCode()).Next(1, 101);

            foreach (EnterpriseChannelRuleAdvance rule in rules)
            {
                if (seed >= rule.BeginSendPercent && seed <= rule.EndSendPercent)
                {
                    return rule.ChannelCode;
                }
            }

            return string.Empty;
        }

        /// <summary>
        /// 根据种子返回该企业的通道号，粗粒度控制，速度慢，精确（当前未用）
        /// </summary>
        /// <param name="rules"></param>
        /// <param name="seed"></param>
        /// <returns></returns>
        private static string GetChannelCode(IList<EnterpriseChannelRule> rules, int seed)
        {
            if (rules.Count == 1)
            {
                return rules[0].ChannelCode;
            }
            else
            {
                for (int i = 0; i < rules.Count; i++)
                {
                    if (seed >= rules[i].BeginSendPercent && seed <= rules[i].EndSendPercent)
                    {
                        return rules[i].ChannelCode;
                    }
                }
            }

            return string.Empty;
        }

        /// <summary>
        /// 根据种子返回该企业的通道号，粗粒度控制，速度快，准确
        /// </summary>
        /// <param name="rules"></param>
        /// <returns></returns>
        private static string GetChannelCode(IList<EnterpriseChannelRule> rules)
        {
            int seed = new Random(Guid.NewGuid().GetHashCode()).Next(1, 101);

            //Output(seed.ToString());

            for (int i = 0; i < rules.Count; i++)
            {
                if (seed >= rules[i].BeginSendPercent && seed <= rules[i].EndSendPercent)
                {
                    //Output(rules[i].ChannelCode);
                    return rules[i].ChannelCode;
                }
            }

            return string.Empty;
        }

        /// <summary>
        /// 获得指定企业的普通通道规则
        /// </summary>
        /// <param name="enterprisecode">企业号</param>
        /// <param name="allrules">所有通道规则数据</param>
        /// <returns></returns>
        private static IList<EnterpriseChannelRule> GetEnterpriseChannelRule(string enterprisecode, Dictionary<string, EnterpriseChannelRule> allrules)
        {
            IList<EnterpriseChannelRule> rules = new List<EnterpriseChannelRule>();

            foreach (EnterpriseChannelRule rule in allrules.Values)
            {
                if (rule.EnterpriseCode == enterprisecode)
                {
                    rules.Add(rule);
                }
            }

            return rules;
        }

        /// <summary>
        /// 获得指定企业的高级通道规则
        /// </summary>
        /// <param name="enterprisecode"></param>
        /// <param name="allrules"></param>
        /// <returns></returns>
        private static Dictionary<string, EnterpriseChannelRuleAdvance> GetAdvanceEnterpriseChannelRule(string enterprisecode, Dictionary<string, EnterpriseChannelRuleAdvance> allrules)
        {
            Dictionary<string, EnterpriseChannelRuleAdvance> rules = new Dictionary<string, EnterpriseChannelRuleAdvance>();

            foreach (EnterpriseChannelRuleAdvance rule in allrules.Values)
            {
                if (rule.EnterpriseCode == enterprisecode)
                {
                    rules.Add(rule.RuleType, rule);
                }
            }

            return rules;
        }

        /// <summary>
        /// 获得指定类型的高级通道规则
        /// </summary>
        /// <param name="type"></param>
        /// <param name="allrules"></param>
        /// <returns></returns>
        private static IList<EnterpriseChannelRuleAdvance> GetAdvanceEnterpriseChannelRuleByType(string type, Dictionary<string, EnterpriseChannelRuleAdvance> allrules)
        {
            IList<EnterpriseChannelRuleAdvance> rules = new List<EnterpriseChannelRuleAdvance>();

            foreach (EnterpriseChannelRuleAdvance rule in allrules.Values)
            {
                if (rule.RuleType == type)
                {
                    rules.Add(rule);
                }
            }

            return rules;
        }

        #endregion

        #region 初始化定时器
        /// <summary>
        /// 初始化定时器
        /// </summary>
        private static void InitilizeTimer()
        {
            // 定时清理控制台
            timerConsole.Interval = RefreshConsoleTime;
            timerConsole.Enabled = true;
            timerConsole.Elapsed += new System.Timers.ElapsedEventHandler(timerConsole_Elapsed);
            timerConsole.AutoReset = true;

            //定时刷新企业数据
            timerEnterprise.Interval = RefreshEnterpriseTime;
            timerEnterprise.Enabled = true;
            timerEnterprise.Elapsed += new System.Timers.ElapsedEventHandler(timerEnterprise_Elapsed);
            timerEnterprise.AutoReset = true;

            //定时刷新通道数据
            timerChannel.Interval = RefreshChannelTime;
            timerChannel.Enabled = true;
            timerChannel.Elapsed += new System.Timers.ElapsedEventHandler(timerChannel_Elapsed);
            timerChannel.AutoReset = true;

            //定时刷新普通规则数据
            timerRule.Interval = RefreshRuleTime;
            timerRule.Enabled = true;
            timerRule.Elapsed += new System.Timers.ElapsedEventHandler(timerRule_Elapsed);
            timerRule.AutoReset = true;

            //定时刷新普通规则数据
            timerAdvanceRule.Interval = RefreshAdvanceRuleTime;
            timerAdvanceRule.Enabled = true;
            timerAdvanceRule.Elapsed += new System.Timers.ElapsedEventHandler(timerAdvanceRule_Elapsed);
            timerAdvanceRule.AutoReset = true;

            //定时刷新自定义规则数据
            timerCustomRule.Interval = RefreshCustomRuleTime;
            timerCustomRule.Enabled = true;
            timerCustomRule.Elapsed += new System.Timers.ElapsedEventHandler(timerCustomRule_Elapsed);
            timerCustomRule.AutoReset = true;

            //timerBlackList.Interval = RefreshBlackListTime;
            //timerBlackList.Enabled = true;
            //timerBlackList.Elapsed += new System.Timers.ElapsedEventHandler(timerBlackList_Elapsed);
            //timerBlackList.AutoReset = true;
        }

        static void timerCustomRule_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            EnterpriseChannelRuleCustomCodeList customrules = GetCustomChannelRule(Enterprises);

            if (!customrules.Equals(ChannelCustomRules))
            {
                try
                {
                    ChannelCustomRules = customrules;

                    Output("自定义发送规则已更新", true);
                }
                catch
                {
                }
            }
        }

        //static void timerBlackList_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        //{
        //    Dictionary<string, Dictionary<string, BlackList>> list = GetBlackList();

        //    if (!list.Equals(BlackLists))
        //    {
        //        try
        //        {
        //            BlackLists = list;

        //            Output("黑名单已更新",true);
        //        }
        //        catch
        //        {
        //        }
        //    }
        //}

        static void timerAdvanceRule_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            EnterpriseChannelRuleAdvanceCodeList advancechannelrules = GetAdvanceChannelRule(Enterprises);

            Dictionary<string, RuleSignExtValue> advance = GetSignExtAdvance();

            if (!advancechannelrules.Equals(ChannelAdvanceRules))
            {
                try
                {
                    ChannelAdvanceRules = advancechannelrules;

                    ChannelAdvanceSignExt = advance;

                    Output("高级发送规则已更新",true);

                    Output("高级签名扩展号规则已更新",true);
                }
                catch
                {
                }
            }

        }

        static void timerRule_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            Dictionary<string, IList<EnterpriseChannelRule>> channelrules = GetChannelRule(Enterprises);

            Dictionary<string, RuleSignExtValue> normal = GetSignExtNormal();

            if (!channelrules.Equals(ChannelRules))
            {
                try
                {
                    ChannelRules = channelrules;

                    ChannelNormalSignExt = normal;

                    Output("普通发送规则已更新",true);

                    Output("普通签名扩展号规则已更新",true);
                }
                catch
                {
                }
            }
        }

        static void timerChannel_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            IList<Channel> channels = GetChannel();

            Dictionary<string, Channel> dicchannels = GetDicChannel();

            if (!channels.Equals(Channels))
            {
                try
                {
                    Channels = channels;

                    DicChannels = dicchannels;

                    Output("通道数据已更新", true);

                    ManageChannels();
                }
                catch
                {
                }
            }
        }

        static void timerEnterprise_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            IList<Enterprise> listenterprise = GetEnterprise();
            Dictionary<string, Enterprise> dicenterprise = GetEnterpriseDic();

            if (!listenterprise.Equals(Enterprises))
            {
                try
                {
                    Enterprises = listenterprise;

                    DicEnterprises = dicenterprise;

                    Output("企业数据已更新",true);

                    ManageThreads();
                }
                catch
                {
                }
            }
        }

        static void timerConsole_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (Debug == 1)
            {
                Console.Clear();
                Output("控制台已更新");
            }
        }
        #endregion

        #region 数据源
        /// <summary>
        /// 获得所有企业
        /// </summary>
        /// <returns></returns>
        private static IList<Enterprise> GetEnterprise()
        {
            IList<Enterprise> listenterprise = QueryOperate<Enterprise>.Create(DataKey).OrderBy(Enterprise._EnterpriseID).List();

            return listenterprise;
        }

        /// <summary>
        /// 获得企业字典
        /// </summary>
        /// <returns></returns>
        private static Dictionary<string,Enterprise> GetEnterpriseDic()
        {
            Dictionary<string, Enterprise> enterprise = new Dictionary<string, Enterprise>();

            IList<Enterprise> listenterprise = QueryOperate<Enterprise>.Create(DataKey).OrderBy(Enterprise._EnterpriseID).List();

            foreach (Enterprise e in listenterprise)
            {
                enterprise.Add(e.EnterpriseCode, e);
            }

            return enterprise;
        }

        /// <summary>
        /// 获得所有通道
        /// </summary>
        /// <returns></returns>
        private static IList<Channel> GetChannel()
        {
            IList<Channel> listchannel = QueryOperate<Channel>.Create(DataKey).OrderBy(Channel._ChannelID).List();

            return listchannel;
        }

        /// <summary>
        /// 获得所有通道
        /// </summary>
        /// <returns></returns>
        private static Dictionary<string,Channel> GetDicChannel()
        {
            Dictionary<string, Channel> dic = new Dictionary<string, Channel>();

            IList<Channel> listchannel = QueryOperate<Channel>.Create(DataKey).OrderBy(Channel._ChannelID).List();

            foreach (Channel channel in listchannel)
            {
                dic.Add(channel.ChannelCode, channel);
            }

            return dic;
        }

        /// <summary>
        /// 获得黑名单
        /// </summary>
        /// <returns></returns>
        private static Dictionary<string, Dictionary<string, BlackList>> GetBlackList()
        {
            Dictionary<string, Dictionary<string, BlackList>> list = new Dictionary<string, Dictionary<string, BlackList>>();

            foreach (Enterprise e in Enterprises)
            {
                IList<BlackList> blacklist = QueryOperate<BlackList>.Create(DataKey).Where(BlackList._EnterpriseCode == e.EnterpriseCode).List();

               Dictionary<string,BlackList> bl=new Dictionary<string,BlackList>();

                foreach(BlackList btemp in blacklist)
                {
                    bl.Add(btemp.Mobile,btemp);
                }
               
            }

            return list;
        }

        private static IList<ChannelType> GetChannelType()
        {
            IList<ChannelType> listchanneltype = QueryOperate<ChannelType>.Create(DataKey).OrderBy(ChannelType._ChannelTypeID).List();

            return listchanneltype;
        }

        /// <summary>
        /// 获得所有普通通道规则
        /// </summary>
        /// <returns></returns>
        private static Dictionary<string, IList<EnterpriseChannelRule>> GetChannelRule(IList<Enterprise> enterprises)
        {
            Dictionary<string, IList<EnterpriseChannelRule>> channelrules = new Dictionary<string, IList<EnterpriseChannelRule>>();

            foreach (Enterprise e in enterprises)
            {
                if (e.SendMethod.ToLower() == "normal")
                {
                    IList<EnterpriseChannelRule> listchannelrule = QueryOperate<EnterpriseChannelRule>.Create(DataKey).Where(EnterpriseChannelRule._EnterpriseCode == e.EnterpriseCode).OrderBy(EnterpriseChannelRule._RuleID).List();

                    channelrules.Add(e.EnterpriseCode, listchannelrule);
                }
            }

            return channelrules;

        }

        /// <summary>
        /// 获得所有普通的通道签名和扩展号
        /// </summary>
        /// <returns></returns>
        private static Dictionary<string, RuleSignExtValue> GetSignExtNormal()
        {
            Dictionary<string, RuleSignExtValue> normal = new Dictionary<string, RuleSignExtValue>();

            RuleSignExtKey key;

            RuleSignExtValue value;

            IList<EnterpriseChannelRule> listchannelrule = QueryOperate<EnterpriseChannelRule>.Create(DataKey).OrderBy(EnterpriseChannelRule._RuleID).List();

            foreach (EnterpriseChannelRule rule in listchannelrule)
            {
                key = new RuleSignExtKey();
                key.ChannelCode = rule.ChannelCode;
                key.EnterpriseCode = rule.EnterpriseCode;

                value = new RuleSignExtValue();
                value.ExtCode = rule.ExtCode;
                value.Sign = rule.Sign;

                normal.Add(key.ToString(), value);
            }

            return normal;
        }

        /// <summary>
        /// 获得所有高级通道规则
        /// </summary>
        /// <returns></returns>
        private static EnterpriseChannelRuleAdvanceCodeList GetAdvanceChannelRule(IList<Enterprise> enterprises)
        {
            EnterpriseChannelRuleAdvanceCodeList channelrules = new EnterpriseChannelRuleAdvanceCodeList();

            foreach (Enterprise e in enterprises)
            {
                if (e.SendMethod.ToLower() == "advance")
                {

                    if (!channelrules.ContainsKey(e.EnterpriseCode))
                    {
                        EnterpriseChannelRuleAdvanceTypeList typeList = new EnterpriseChannelRuleAdvanceTypeList();
                        channelrules.Add(e.EnterpriseCode, typeList);
                    }

                    foreach (ChannelType type in ChannelTypes)
                    {
                        channelrules[e.EnterpriseCode].Add(type.ChannelTypeCode, new EnterpriseChannelRuleAdvanceItemList());

                        IList<EnterpriseChannelRuleAdvance> types = QueryOperate<EnterpriseChannelRuleAdvance>.Create(DataKey).Where(EnterpriseChannelRuleAdvance._EnterpriseCode == e.EnterpriseCode & EnterpriseChannelRuleAdvance._RuleType == type.ChannelTypeCode).OrderBy(EnterpriseChannelRuleAdvance._RuleID).List();

                        foreach (EnterpriseChannelRuleAdvance temp in types)
                        {
                            channelrules[e.EnterpriseCode][type.ChannelTypeCode].Add(temp);
                        }

                    }
                }

            }

            return channelrules;
        }

        /// <summary>
        /// 获得自定义通道规则
        /// </summary>
        /// <param name="enterprises"></param>
        /// <returns></returns>
        private static EnterpriseChannelRuleCustomCodeList GetCustomChannelRule(IList<Enterprise> enterprises)
        {
            EnterpriseChannelRuleCustomCodeList channelrules = new EnterpriseChannelRuleCustomCodeList();

            foreach (Enterprise e in enterprises)
            {
                if (e.SendMethod.ToLower() == "custom")
                {

                    if (!channelrules.ContainsKey(e.EnterpriseCode))
                    {
                        EnterpriseChannelRuleCustomTypeList typeList = new EnterpriseChannelRuleCustomTypeList();
                        channelrules.Add(e.EnterpriseCode, typeList);
                    }

                    foreach (ChannelType type in ChannelTypes)
                    {
                        EnterpriseChannelRuleCustom rule = QueryOperate<EnterpriseChannelRuleCustom>.Create(DataKey).Where(
                            EnterpriseChannelRuleCustom._EnterpriseCode == e.EnterpriseCode & EnterpriseChannelRuleCustom._RuleType == type.ChannelTypeCode).Get();

                        channelrules[e.EnterpriseCode].Add(type.ChannelTypeCode, rule);

                    }
                }
            }

            return channelrules;
        }

        /// <summary>
        /// 获得所有高级的通道签名和扩展号
        /// </summary>
        /// <returns></returns>
        private static Dictionary<string, RuleSignExtValue> GetSignExtAdvance()
        {
            Dictionary<string, RuleSignExtValue> normal = new Dictionary<string, RuleSignExtValue>();

            RuleSignExtKeyAdvance key;

            RuleSignExtValue value;

            IList<EnterpriseChannelRuleAdvance> listchannelrule = QueryOperate<EnterpriseChannelRuleAdvance>.Create(DataKey).OrderBy(EnterpriseChannelRuleAdvance._RuleID).List();

            foreach (EnterpriseChannelRuleAdvance rule in listchannelrule)
            {
                key = new RuleSignExtKeyAdvance();
                key.ChannelCode = rule.ChannelCode;
                key.EnterpriseCode = rule.EnterpriseCode;
                key.RuleType = rule.RuleType;

                value = new RuleSignExtValue();
                value.ExtCode = rule.ExtCode;
                value.Sign = rule.Sign;

                normal.Add(key.ToString(), value);
            }

            return normal;
        }

        #endregion

        #region 调试辅助逻辑
        private static string GetDateTime()
        {
            return "[" + DateTime.Now.ToString("HH:mm:ss") + "] ";
        }

        private static void Output(string msg)
        {
            lock (obj)
            {
                if (Debug == 1)
                {
                    Console.WriteLine(GetDateTime() + msg);
                }
            }
        }

        private static void Output(string msg,bool log)
        {
            lock (obj)
            {
                if (Debug == 1)
                {
                    Console.WriteLine(GetDateTime() + msg);
                }

                if (log)
                {
                    if (LogToFile)
                    {
                        Log.WriteToFile(ServiceDirectory + @"\log_" + DateTime.Now.ToString("yyyyMMdd") + ".txt", GetDateTime() + msg);
                    }
                }
            }
        }

        private static void Output(string msg, ConsoleColor color)
        {
            lock (obj)
            {
                if (Debug == 1)
                {
                    Console.ForegroundColor = color;
                    Console.WriteLine(GetDateTime() + msg);
                    Console.ResetColor();
                }
            }
        }

        private static void Output(string msg, ConsoleColor color,bool log)
        {
            lock (obj)
            {
                if (Debug == 1)
                {
                    Console.ForegroundColor = color;
                    Console.WriteLine(GetDateTime() + msg);
                    Console.ResetColor();
                }

                if (log)
                {
                    if (LogToFile)
                    {
                        Log.WriteToFile(ServiceDirectory + @"\log_" + DateTime.Now.ToString("yyyyMMdd") + ".txt", GetDateTime() + msg);
                    }
                }
            }
        }
        #endregion
    }

    #region 辅助类
    public class EnterpriseChannelRuleAdvanceCodeList : Dictionary<string, EnterpriseChannelRuleAdvanceTypeList>
    {
    }

    public class EnterpriseChannelRuleAdvanceTypeList : Dictionary<string, EnterpriseChannelRuleAdvanceItemList>
    {
    }

    public class EnterpriseChannelRuleAdvanceItemList : List<EnterpriseChannelRuleAdvance>
    {
    }

    public class EnterpriseChannelRuleCustomTypeList : Dictionary<string, EnterpriseChannelRuleCustom>
    {
    }

    public class EnterpriseChannelRuleCustomCodeList : Dictionary<string, EnterpriseChannelRuleCustomTypeList>
    {
    }

    /// <summary>
    /// 按照企业号和通道号组成的key
    /// </summary>
    public class RuleSignExtKey
    {
        private string enterprisecode;
        private string channelcode;

        public string EnterpriseCode
        {
            get
            {
                return this.enterprisecode;
            }
            set
            {
                this.enterprisecode = value;
            }
        }

        public string ChannelCode
        {
            get
            {
                return this.channelcode;
            }
            set
            {
                this.channelcode = value;
            }
        }

        public override string ToString()
        {
            return EnterpriseCode + "," + ChannelCode;
        }
    }

    /// <summary>
    /// 按照企业号和通道号，通道类型组成的key
    /// </summary>
    public class RuleSignExtKeyAdvance : RuleSignExtKey
    {
        private string ruletype;

        public string RuleType
        {
            get
            {
                return this.ruletype;
            }
            set
            {
                this.ruletype = value;
            }
        }

        public override string ToString()
        {
            return base.ToString() + "," + RuleType;
        }
    }

    /// <summary>
    /// 根据指定key生成的签名和扩展号value
    /// </summary>
    public class RuleSignExtValue
    {
        private string sign;
        private string extcode;

        public string Sign
        {
            get
            {
                return this.sign;
            }
            set
            {
                this.sign = value;
            }
        }

        public string ExtCode
        {
            get
            {
                return this.extcode;
            }
            set
            {
                this.extcode = value;
            }
        }
    }

    public class Portal
    {
        private IContainer container;
        private NotifyIcon notifyIcon;

        public Portal()
        {
            //Icon icon = new Icon(SystemIcons.Application, 16, 16);
            Icon icon = new Icon(GetEmbeddedResource("FundSms.Server.Platform.MailButton.ico"), 16, 16);
            this.container = new Container();
            this.notifyIcon = new NotifyIcon(this.container);
            this.notifyIcon.Icon = icon;
            this.notifyIcon.Visible = true;
            this.notifyIcon.Text = "数米网短信分发服务";
            
        }

        public void Dispose()
        {
            this.notifyIcon.Dispose();
        }

        public System.IO.Stream GetEmbeddedResource(string strname)
        {
            return System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(strname);
        }

    }
    #endregion
}
